package com.liy.jiagou.sso.auth.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

// import org.springframework.data.redis.connection.RedisConnectionFactory;

import org.springframework.security.authentication.AuthenticationManager;



// security.oauth2
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;

// import org.springframework.security.oauth2.provider.ClientDetailsService;
// import org.springframework.security.oauth2.provider.client.JdbcClientDetailsService;
// import org.springframework.security.oauth2.provider.token.TokenStore;
// import org.springframework.security.oauth2.provider.token.store.JdbcTokenStore;
// import org.springframework.security.oauth2.provider.token.store.redis.RedisTokenStore;

import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;


// import javax.sql.DataSource;

/**
 *
 *  认证授权服务配置   包 org.springframework.security.oauth2
 *
 *  security-oauth2 依赖于 security;  这二者的层次关系
 *
 *
 **/
@Configuration
@EnableAuthorizationServer
public class OAuth2AuthorizationServerConfig  extends AuthorizationServerConfigurerAdapter {



    /**
     * 用户认证 Manager
     */
    @Autowired
    private AuthenticationManager authenticationManager;


    /**
     * 数据源 DataSource
     */
    //@Autowired
    //private DataSource dataSource;


    /**
     * Redis 连接的工厂
     */
//    @Autowired
//    private RedisConnectionFactory redisConnectionFactory;


     /**
     * Token 存储器  JDBC
     */
//    @Bean
//    public TokenStore jdbcTokenStore() {
//        return new JdbcTokenStore(dataSource);
//    }



    /**
     * Token 存储器  Redis
     */
//    @Bean
//    public TokenStore redisTokenStore() {
//        return new RedisTokenStore(redisConnectionFactory);
//    }


    // Jwt-Token的转换器
    @Bean
    public JwtAccessTokenConverter jwtAccessTokenConverter() {
        JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
        converter.setSigningKey("jwt_secret");   // JWT 秘钥
        return converter;
    }

    // Token 存储器  JWT
    @Bean
    public JwtTokenStore jwtTokenStore() {
        return new JwtTokenStore(jwtAccessTokenConverter());
    }


    // 授权详细配置
    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints.authenticationManager(authenticationManager)   // 用户认证 Manager
                .tokenStore(jwtTokenStore())                     // Token 存储器

                .accessTokenConverter(jwtAccessTokenConverter());  // 额外增加的  Jwt-Token 的转换器

    }



    // 安全控制
    @Override
    public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
        oauthServer.checkTokenAccess("permitAll()");      //  或者 "permitAll()"
        oauthServer.allowFormAuthenticationForClients();

    }


    /**
     * 配置 Client 详情管理器 JDBC
     */
//    @Bean
//    public ClientDetailsService jdbcClientDetailsService() {
//        return new JdbcClientDetailsService(dataSource);
//    }


    /**
     *  注册 Client 详情管理器
     */
    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        //clients.withClientDetails(jdbcClientDetailsService());
        clients.inMemory()

                .withClient("clientapp").secret("112233")//
                .authorizedGrantTypes("password", "authorization_code", "refresh_token")  // password, authorization_code, refresh_token
                .scopes("read_userinfo", "read_contacts" ,"all")//

                .and() //

                .withClient("client-sys").secret("112233")//
                .authorizedGrantTypes("password", "authorization_code", "refresh_token")  // password, authorization_code, refresh_token
                .scopes("read_userinfo", "read_contacts" ,"all") //

                .and()//

                .withClient("client-product").secret("112233")//
                .authorizedGrantTypes("password", "authorization_code", "refresh_token")  // password, authorization_code, refresh_token
                .scopes("read_userinfo", "read_contacts" ,"all") //

                .and()//

                .withClient("client-pw").secret("112233")//
                .authorizedGrantTypes("password", "authorization_code", "refresh_token")  // password, authorization_code, refresh_token
                .scopes("read_userinfo", "read_contacts" ,"all"); //

    }
}
